{
  rules+: [
    {
      // 根据过往6小时增长数据,预测未来硬盘使用趋势
      alert: 'NodeFilesystemSpaceFillingUp',
      annotations: {
        message: '{{ $labels.instance }} 下挂载目录 {{ $labels.device }} 只剩下 {{ printf "%.2f" $value }}% 可用空间',
        summary: 'Filesystem is predicted to run out of space within the next 24 hours.',
        runbook: $._config.runbook,
      },
      expr: |||
        (node_filesystem_avail_bytes{%(fsSelector)s, %(nodeExporterSelector)s} / node_filesystem_size_bytes{%(fsSelector)s, %(nodeExporterSelector)s} * 100 < 40 and predict_linear(node_filesystem_avail_bytes{%(fsSelector)s, %(nodeExporterSelector)s}[6h], 24 * 60 * 60) < 0 and node_filesystem_readonly{%(fsSelector)s, %(nodeExporterSelector)s} == 0)
      ||| % $._config,
      'for': '1h',
      labels: {
        severity: 'warning',
      },
    },
    {
      // 根据过往6小时增长数据,预测未来硬盘使用趋势
      alert: 'NodeFilesystemSpaceFillingUp',
      annotations: {
        message: '{{ $labels.instance }} 下挂载目录 {{ $labels.device }} 只剩下 {{ printf "%.2f" $value }}% 可用空间',
        summary: 'Filesystem is predicted to run out of space within the next 4 hours.',
        runbook: $._config.runbook,
      },
      expr: |||
        (node_filesystem_avail_bytes{%(fsSelector)s, %(nodeExporterSelector)s} / node_filesystem_size_bytes{%(fsSelector)s, %(nodeExporterSelector)s} * 100 < 15 and predict_linear(node_filesystem_avail_bytes{%(fsSelector)s, %(nodeExporterSelector)s}[6h], 4 * 60 * 60) < 0 and node_filesystem_readonly{%(fsSelector)s, %(nodeExporterSelector)s} == 0)
      ||| % $._config,
      'for': '1h',
      labels: {
        severity: 'critical',
      },
    },
    {
      // 硬盘可用小于15%
      alert: 'NodeFilesystemAlmostOutOfSpace',
      annotations: {
        message: '{{ $labels.instance }} 下挂载目录 {{ $labels.device }} 只剩下 {{ printf "%.2f" $value }}% 可用空间',
        summary: 'Filesystem has less than 15% space left.',
        runbook: $._config.runbook,
      },
      expr: |||
        (node_filesystem_avail_bytes{%(fsSelector)s, %(nodeExporterSelector)s} / node_filesystem_size_bytes{%(fsSelector)s, %(nodeExporterSelector)s} * 100 < 15 and node_filesystem_readonly{%(fsSelector)s, %(nodeExporterSelector)s} == 0)
      ||| % $._config,
      'for': '1h',
      labels: {
        severity: 'warning',
      },
    },
    {
      // 硬盘可用小于5%
      alert: 'NodeFilesystemAlmostOutOfSpace',
      annotations: {
        message: '{{ $labels.instance }} 下挂载目录 {{ $labels.device }} 只剩下 {{ printf "%.2f" $value }}% 可用空间',
        summary: 'Filesystem has less than 5% space left.',
        runbook: $._config.runbook,
      },
      expr: |||
        (node_filesystem_avail_bytes{%(fsSelector)s, %(nodeExporterSelector)s} / node_filesystem_size_bytes{%(fsSelector)s, %(nodeExporterSelector)s} * 100 < 5 and node_filesystem_readonly{%(fsSelector)s, %(nodeExporterSelector)s} == 0)
      ||| % $._config,
      'for': '1h',
      labels: {
        severity: 'critical',
      },
    },
    {
      // 通过过往数据, 预测inode节点使用率
      alert: 'NodeFilesystemFilesFillingUp',
      annotations: {
        message: '{{ $labels.instance }} 下挂载目录 {{ $labels.device }} 只剩下 {{ printf "%.2f" $value }}% 可用 inode 节点',
        summary: 'Filesystem is predicted to run out of inodes within the next 24 hours.',
        runbook: $._config.runbook,
      },
      expr: |||
        (node_filesystem_files_free{%(fsSelector)s, %(nodeExporterSelector)s} / node_filesystem_files{%(fsSelector)s, %(nodeExporterSelector)s} * 100 < 40 and predict_linear(node_filesystem_files_free{%(fsSelector)s, %(nodeExporterSelector)s}[6h], 24 * 60 * 60) < 0 and node_filesystem_readonly{%(fsSelector)s, %(nodeExporterSelector)s} == 0)
      ||| % $._config,
      'for': '1h',
      labels: {
        severity: 'warning',
      },
    },
    {
      // 通过过往数据, 预测inode节点使用率
      alert: 'NodeFilesystemFilesFillingUp',
      annotations: {
        message: '{{ $labels.instance }} 下挂载目录 {{ $labels.device }} 只剩下 {{ printf "%.2f" $value }}% 可用 inode 节点',
        summary: 'Filesystem is predicted to run out of inodes within the next 4 hours.',
        runbook: $._config.runbook,
      },
      expr: |||
        (node_filesystem_files_free{%(fsSelector)s, %(nodeExporterSelector)s} / node_filesystem_files{%(fsSelector)s, %(nodeExporterSelector)s} * 100 < 20 and predict_linear(node_filesystem_files_free{%(fsSelector)s, %(nodeExporterSelector)s}[6h], 4 * 60 * 60) < 0 and node_filesystem_readonly{%(fsSelector)s, %(nodeExporterSelector)s} == 0)
      ||| % $._config,
      'for': '1h',
      labels: {
        severity: 'critical',
      },
    },
    {
      // 低于5% Inode 挂载目录
      alert: 'NodeFilesystemAlmostOutOfFiles',
      annotations: {
        message: '{{ $labels.instance }} 下挂载目录 {{ $labels.device }} 只剩下 {{ printf "%.2f" $value }}% 可用 inode 节点',
        summary: 'Filesystem has less than 5% inodes left.',
        runbook: $._config.runbook,
      },
      expr: |||
        '(node_filesystem_files_free{%(fsSelector)s, %(nodeExporterSelector)s} / node_filesystem_files{%(fsSelector)s, %(nodeExporterSelector)s} * 100 < 5 and node_filesystem_readonly{%(fsSelector)s, %(nodeExporterSelector)s} == 0)'
      ||| % $._config,
      'for': '1h',
      labels: {
        severity: 'warning',
      },
    },
    {
      // 低于3% Inode挂载目录
      alert: 'NodeFilesystemAlmostOutOfFiles',
      annotations: {
        message: '{{ $labels.instance }} 下挂载目录 {{ $labels.device }} 只剩下 {{ printf "%.2f" $value }}% 可用 inode 节点',
        summary: 'Filesystem has less than 3% inodes left.',
        runbook: $._config.runbook,
      },
      expr: |||
        '(node_filesystem_files_free{%(fsSelector)s, %(nodeExporterSelector)s} / node_filesystem_files{%(fsSelector)s, %(nodeExporterSelector)s} * 100 < 3 and node_filesystem_readonly{%(fsSelector)s, %(nodeExporterSelector)s} == 0)'
      ||| % $._config,
      'for': '1h',
      labels: {
        severity: 'critical',
      },
    },
     {
      // 主机磁盘读取异常
      alert: 'NodeUnusualDiskReadRate',
      annotations: {
        message: '节点磁盘可能正在读取大量数据 (> 50 MB/s)  当前值 = {{ $value }}  告警主机: {{ $labels.instance }}',
        summary: 'Node unusual disk read rate (instance {{ $labels.instance }}).',
        runbook: $._config.runbook,
      },
      expr: |||
        sum by (instance) (rate(node_disk_read_bytes_total[2m])) / 1024 / 1024 > 50
      ||| % $._config,
      'for': '5m',
      labels: {
        severity: 'warning',
      },
    },
     {
      // 主机磁盘写入异常
      alert: 'NodeUnusualDiskWriteRate',
      annotations: {
        message: '节点磁盘可能正在写入大量数据 (> 50 MB/s)  当前值 = {{ $value }}  告警主机: {{ $labels.instance }}',
        summary: 'Node unusual disk write rate (instance {{ $labels.instance }}).',
        runbook: $._config.runbook,
      },
      expr: |||
        sum by (instance) (rate(node_disk_written_bytes_total[2m])) / 1024 / 1024 > 50
      ||| % $._config,
      'for': '5m',
      labels: {
        severity: 'warning',
      },
    },
     {
      // 主机磁盘异常读取延迟
      alert: 'NodeUnusualDiskReadLatency',
      annotations: {
        message: '磁盘读取延迟正在增长 (读操作 > 100ms)  当前值 = {{ $value }}  告警主机: {{ $labels.instance }}',
        summary: 'Node unusual disk read latency (instance {{ $labels.instance }}).',
        runbook: $._config.runbook,
      },
      expr: |||
         rate(node_disk_read_time_seconds_total[1m]) / rate(node_disk_reads_completed_total[1m]) > 0.1 and rate(node_disk_reads_completed_total[1m]) > 0
      ||| % $._config,
      'for': '2m',
      labels: {
        severity: 'warning',
      },
    },
     {
      // 主机磁盘异常写入延迟
      alert: 'NodeUnusualDiskWriteLatency',
      annotations: {
        message: '磁盘写入延迟正在增长 (写操作 > 100ms)  当前值 = {{ $value }}  告警主机: {{ $labels.instance }}',
        summary: 'Node unusual disk write latency (instance {{ $labels.instance }}).',
        runbook: $._config.runbook,
      },
      expr: |||
         rate(node_disk_write_time_seconds_total[1m]) / rate(node_disk_writes_completed_total[1m]) > 0.1 and rate(node_disk_writes_completed_total[1m]) > 0
      ||| % $._config,
      'for': '2m',
      labels: {
        severity: 'warning',
      },
    },
  ],
}

